`timescale 1ns / 1ps

module sm4_top_tb;
    reg clk;
    reg reset_n;
    reg sm4_enable_in;
    reg encdec_enable_in;
    reg encdec_sel_in;
    reg valid_in;
    reg [127:0] data_in;
    reg enable_key_exp_in;
    reg user_key_valid_in;
    reg [127:0] user_key_in;
    wire ready_out;
    wire [127:0] result_out;
    wire key_exp_ready_out;
    sm4_top uut (
        .clk(clk),
        .reset_n(reset_n),
        .sm4_enable_in(sm4_enable_in),
        .encdec_enable_in(encdec_enable_in),
        .encdec_sel_in(encdec_sel_in),
        .valid_in(valid_in),
        .data_in(data_in),
        .enable_key_exp_in(enable_key_exp_in),
        .user_key_valid_in(user_key_valid_in),
        .user_key_in(user_key_in),
        .ready_out(ready_out),
        .result_out(result_out),
        .key_exp_ready_out(key_exp_ready_out)
    );
    reg [127:0] expected_ciphertext = 128'h681EDF34D206965E86B3E94F536E4246;
    always #5 clk = ~clk;
    initial begin
        clk = 0;
        reset_n = 0;
        sm4_enable_in = 0;
        encdec_enable_in = 0;
        encdec_sel_in = 0;
        valid_in = 0;
        data_in = 0;
        enable_key_exp_in = 0;
        user_key_valid_in = 0;
        user_key_in = 0;
        #10 reset_n = 1;
        #10;
        enable_key_exp_in = 1;
        user_key_valid_in = 1;
        user_key_in = 128'h0123456789ABCDEFFEDCBA9876543210;
        wait(key_exp_ready_out == 1);
        #10;
        enable_key_exp_in = 0;
        user_key_valid_in = 0;
        #10;
        sm4_enable_in = 1;
        encdec_enable_in = 1;
        encdec_sel_in = 0;
        #10;
        valid_in = 1;
        data_in = 128'h0123456789ABCDEFFEDCBA9876543210;
        wait(ready_out == 1);
        #10;
        valid_in = 0;
        #10;
        $display("====================================");
        $display("Test Case: Standard SM4 Encryption");
        $display("Plaintext: 0123456789ABCDEFFEDCBA9876543210");
        $display("Key:       0123456789ABCDEFFEDCBA9876543210");
        $display("Expected:  681EDF34D206965E86B3E94F536E4246");
        $display("Actual:    %h", result_out);
        
        if (result_out === expected_ciphertext) begin
            $display("Result: PASS - Encryption output matches expected ciphertext");
        end else begin
            $display("Result: FAIL - Encryption output does not match expected ciphertext");
        end
        $display("====================================");
        #100;
        $finish;
    end
    initial begin
        $monitor("Time = %0t: ready_out=%b, result_out=%h", $time, ready_out, result_out);
    end
    
endmodule